import os
import sys

from st2client.client import Client
from st2common.runners.base_action import Action

ENDPOINT = 'ST2_ACTION_API_URL'
AUTH_TOKEN = 'ST2_ACTION_AUTH_TOKEN'

ACTION_EXECUTION = 'action_executions'
ACTION_EXECUTION_STATUS = ['succeeded', 'failed']


class TicketAction(Action):

    def __init__(self, config=None, action_service=None):
        super(TicketAction, self).__init__(config, action_service)
        self._client = None

    def run(self, **kwargs):
        payload = kwargs.get('payload', {})
        params = {
            'limit': 50,
            'sort_desc': True,
            'trace_tag': payload.get('trace_tag')
        }
        actions = self.client.trace.query(**{'params': params})
        data = []
        for trace in actions:
            trace_payload = trace.to_dict()
            if isinstance(trace_payload, list):
                self.logger.info("trace payload is list : {}".format(trace_payload))
                continue
            if self.is_not_execution(trace_payload):
                continue
            if not self.execution_is_finish(trace_payload):
                # trace tag tasks not finish
                self.logger.info("Task is not finished {} ".format(trace_payload))
                return
            data.append(trace_payload)
        self.logger.info("Task is success")
        self.logger.info("TicketAction query actions: {} {} ".format(actions, data))
        sys.exit(0)

    @property
    def client(self):
        if not self._client:
            base_url, api_url, auth_url = self._get_st2_urls()
            token = self._get_auth_token()
            cacert = self._get_cacert()

            client_kwargs = {}
            if cacert:
                client_kwargs['cacert'] = cacert

            self._client= Client(base_url=base_url,
                                 api_url=api_url,
                                 auth_url=auth_url,
                                 token=token,
                                 **client_kwargs)
        return self._client

    @staticmethod
    def _get_auth_token():
        return os.environ.get(AUTH_TOKEN, None)

    def _get_cacert(self):
        cacert = self.config.get('cacert', None)
        return cacert

    def _get_st2_urls(self):
        base_url = self.config.get('base_url', None)
        api_url = self.config.get('api_url', None)
        auth_url = self.config.get('auth_url', None)

        if not base_url:
            api_url = os.environ.get('ST2_ACTION_API_URL', None)
            auth_url = os.environ.get('ST2_ACTION_AUTH_URL', None)

        return base_url, api_url, auth_url

    @staticmethod
    def is_not_execution(payload):
        return payload.get(ACTION_EXECUTION) is None

    def execution_is_finish(self, payload):
        payload = payload.get(ACTION_EXECUTION, {})
        if not isinstance(payload, list):
            payload = [payload]
        action_status = []
        for data in payload:
            if not isinstance(data, dict):
                try:
                    data = data.to_dict()
                except:
                    return False
            instance = data.get('object_id', None)
            if not instance:
                return False
            response = self.client.liveactions.get_by_id(instance)
            response = response.to_dict()
            action_status.append(response.get('status', None))
        self.logger.info("Task execution {}".format(action_status))
        return all([status in ACTION_EXECUTION_STATUS for status in action_status])
